package com.thwj.project.app.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.thwj.framework.redis.RedisCache;
import com.thwj.framework.web.service.TokenService;
import com.thwj.project.amap.AMapService;
import com.thwj.project.amap.dto.AppLocationDTO;
import com.thwj.project.amap.jsonbean.AMapLocation;
import com.thwj.project.app.api.vo.CityViewVo;
import com.thwj.project.app.api.vo.CityVo;
import com.thwj.project.biz.domain.Area;
import com.thwj.project.biz.service.IAreaService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Transactional
@Service
public class AppAreaService {

    @Autowired
    RedisCache redisCache;
    @Autowired
    IAreaService areaService;
    @Autowired
    AMapService aMapService;
    @Autowired
    TokenService tokenService;

    /***
     * redis key值 行政区域 城市数据
     */
    public static final String REDIS_CITY_LIST = "city_list";


    public List<CityViewVo> getCityViewVoList() {
        List<CityViewVo> cityViewVoList = redisCache.getCacheList(REDIS_CITY_LIST);
        if(CollectionUtils.isEmpty(cityViewVoList)) {
            // 数据库读取
            List<Area> areaList = areaService.list(
                    new QueryWrapper<Area>().groupBy("city_code,city_name,city_first_letter")
                            .select("city_code as cityCode,city_name as cityName,city_first_letter as cityFirstLetter")
            );
            cityViewVoList = convertCityViewVoList(areaList);
            redisCache.setCacheList(REDIS_CITY_LIST,cityViewVoList);
        }
        return cityViewVoList;
    }

    private List<CityViewVo> convertCityViewVoList(List<Area> areaList) {
        // 分组展示
        Map<String,List<Area>> cityFirstLetterListMap = areaList.stream()
                .collect(Collectors.groupingBy(item -> item.getCityFirstLetter(), Collectors.toList()));
        // key排序
        Set<String> sortSet = new TreeSet<>(Comparator.naturalOrder());
        sortSet.addAll(cityFirstLetterListMap.keySet());
        List<CityViewVo> viewVos = new ArrayList<>();
        for (String firstLetter : sortSet) {
            CityViewVo cityViewVo = new CityViewVo();
            cityViewVo.setCityFirstLetter(firstLetter);
            List<Area> keyAreaList = cityFirstLetterListMap.get(firstLetter);
            List<CityVo> cityVoList = new ArrayList<>();
            if(!CollectionUtils.isEmpty(keyAreaList)) {
                cityVoList = keyAreaList.stream().map(item->{
                    CityVo cityVo = new CityVo();
                    cityVo.setCityCode(item.getCityCode());
                    cityVo.setCityName(item.getCityName());
                    return cityVo;
                }).collect(Collectors.toList());
            }
            cityViewVo.setCityVoList(cityVoList);
            viewVos.add(cityViewVo);
        }
        return viewVos;
    }


    public AppLocationDTO getAppLocationVo(Boolean needDefault) {
        String lngLat = tokenService.getLngLat();
        // 返回一个默认城市
        if(lngLat == null) {
            // 默认一个区
            if(needDefault) {
                Area defaultArea = areaService.getById(110101L);
                return convertAppLocationDTO(defaultArea);
            }
            return null;
        }
        return getAppLocationVoByLngLat(lngLat);
    }

    public AppLocationDTO getAppLocationVoByLngLat(String lngLat) {
        AMapLocation aMapLocation = aMapService.getAMapLocation(lngLat);
        Long acode = Long.parseLong(aMapLocation.getRegeocode().getAddressComponent().getAdcode());
        Area areaLngLat = areaService.getById(acode);
        return convertAppLocationDTO(areaLngLat);
    }

    private AppLocationDTO convertAppLocationDTO(Area area){
        AppLocationDTO appLocationDTO = new AppLocationDTO();
        appLocationDTO.setCodeCity(area.getCityCode());
        appLocationDTO.setNameCity(area.getCityName());
        appLocationDTO.setCodeDistrict(area.getAreaCode());
        appLocationDTO.setNameDistrict(area.getAreaName());
        appLocationDTO.setCodeProv(area.getProCode());
        appLocationDTO.setNameProv(area.getProName());
        return appLocationDTO;
    }
}
